Skip to main content

在浏览器里,从输入 URL 到页面展示,这中间发生了什么?

导航流程

用户发出 URL 请求到页面开始解析的这个过程,就叫做导航。如图:

浏览器导航流程

简单总结:

  1. 用户输入 url 并回车

  2. 浏览器进程检查 url,组装协议,构成完整的 url

  3. 浏览器进程通过进程间通信(IPC)把 url 请求发送给网络进程

  4. 网络进程接收到 url 请求后检查本地缓存是否缓存了该请求资源,如果有则将该资源返回给浏览器进程

  5. 如果没有,网络进程向 web 服务器发起 http 请求(网络请求),请求流程如下:

    5.1 进行 DNS 解析,获取服务器 ip 地址,端口(端口是通过 dns 解析获取的吗?这里有个疑问)

    5.2 利用 ip 地址和服务器建立 tcp 连接

    5.3 构建请求头信息

    5.4 发送请求头信息

    5.5 服务器响应后,网络进程接收响应头和响应信息,并解析响应内容

  6. 网络进程解析响应流程;

    6.1 检查状态码,如果是 301/302,则需要重定向,从 Location 自动中读取地址,重新进行第 4 步(301/302 跳转也会读取本地缓存吗?这里有个疑问),如果是 200,则继续处理请求。

    6.2 200 响应处理: 检查响应类型 Content-Type,如果是字节流类型,则将该请求提交给下载管理器,该导航流程结束,不再进行后续的渲染,如果是 html 则通知浏览器进程准备渲染进程准备进行渲染。

    网络进程解析 HTTP 出来响应头数据,并将其转发给浏览器进程

  7. 准备渲染进程

    7.1 浏览器进程检查当前 url 是否和之前打开的渲染进程根域名是否相同,如果相同,则复用原来的进程,如果不同,则开启新的渲染进程

  8. 传输数据、更新状态

    8.1 浏览器进程接收到网络进程的响应头数据之后,发送 CommitNavigation 消息到渲染进程,发送 CommitNavigation 时会携带响应头、等基本信息。

    8.2 渲染进程接收到 CommitNavigation 消息之后,便开始准备接收 HTML 数据,接收数据的方式是直接和网络进程建立数据管道

    8.3 渲染进程会向浏览器进程“确认提交”,这是告诉浏览器进程,说我已经准备好接受和解析页面数据了

    8.4 浏览器进程更新页面状态。

渲染流程

概括来说,渲染的几个阶段是:构建 DOM 树、样式计算(生成 styleSheets)、布局阶段、分层(生成 layer tree)、绘制(生成绘制指令列表)、分块、光栅化(生成位图)、合成、显示,最后就在显示器上看到请求的页面。下图是完整的渲染流水线示意图: 渲染流程

每个阶段都有输入,处理过程和输入内容

  • 构建 DOM 树(Parse HTML):输入 HTML 文件,由 HTML 解析器解析,输出树状结构的 DOM

  • 样式计算(Recalculate style):

    1. 把 css 转换为浏览器能够理解的结构

      接收 css 文本(外部 style,内部 style,行内 style),输出 styleSheets

    2. 属性值标准化,例如颜色的英文单词转换为 rgb 值等

    3. 计算 DOM 树中每个节点的具体样式

    该过程最终输出每个 DOM 节点的样式,被保存在 ComputedStyle 结构中

  • 布局阶段(Layout),就是计算DOM元素的几何位置信息

    1. 创建布局树

      遍历DOM树,去除不可见元素,最终生成只包含可见元素的布局树

    2. 布局计算,计算布局树节点的位置

    本步骤最终输出布局树

  • 分层(Update Layer tree)

    根据布局树,生成图层树

  • 图层绘制(paint)

    把每个图层的绘制拆分成绘制指令,这些绘制指令按照顺序组成绘制列表。本步骤的输出内容就是绘制列表

到此渲染进程的主线程工作结束,把绘制列表交给合成线程

  • 栅格化,即生成位图的过程

    1. 图层分块

    2. 合成线程优先栅格化视口附近的图块

    3. 栅格化通常会使用GPU加速生成,生成的位图保存在GPU内存中

  • 显示

    栅格化结束后,合成线程发送通知给浏览器进程,根据通知浏览器将页面内容合成到内存中,最后显示在屏幕上

重排和重绘

重排,会触发上述的完整流程

重绘,DOM结构没变,会跳过layout和layer tree阶段,生成新的绘制列表

css transform动画,会跳过layout,layer tree,paint,直接进入合成线程阶段